<script setup lang="ts">
import { ref, computed } from 'vue'

const props = defineProps<{
  items: any[]
  itemHeight: number
  visibleItems: number
}>()

const scrollTop = ref(0)

const totalHeight = computed(() => 
  props.items.length * props.itemHeight
)

const visibleRange = computed(() => {
  const start = Math.floor(scrollTop.value / props.itemHeight)
  const end = start + props.visibleItems
  return {
    start: Math.max(0, start - 1),
    end: Math.min(props.items.length, end + 1)
  }
})

const visibleItems = computed(() => 
  props.items.slice(visibleRange.value.start, visibleRange.value.end)
)

const containerStyle = computed(() => ({
  height: `${props.visibleItems * props.itemHeight}px`,
  overflow: 'auto'
}))

const contentStyle = computed(() => ({
  height: `${totalHeight.value}px`,
  position: 'relative' as const
}))

const handleScroll = (e: Event) => {
  scrollTop.value = (e.target as HTMLElement).scrollTop
}
</script>

<template>
  <div 
    class="virtual-list" 
    :style="containerStyle"
    @scroll="handleScroll"
  >
    <div class="content" :style="contentStyle">
      <div
        v-for="(item, index) in visibleItems"
        :key="item.id"
        class="list-item"
        :style="{
          position: 'absolute',
          top: `${(index + visibleRange.start) * itemHeight}px`,
          height: `${itemHeight}px`
        }"
      >
        {{ item.text }}
      </div>
    </div>
  </div>
</template>

<style scoped>
.virtual-list {
  border: 1px solid #ddd;
  border-radius: 4px;
}

.list-item {
  padding: 10px;
  border-bottom: 1px solid #eee;
  width: 100%;
  box-sizing: border-box;
  display: flex;
  align-items: center;
}
</style> 